Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/src/packages/next/pages/token/[id].tsx
Views: 687
/*1* This file is part of CoCalc: Copyright © 2021 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45/*6Visit78https://cocalc.com/token/vZmCKcIMha2nKyFQ0rgK910to carry out the action associated with the token vZmCKcIMha2nKyFQ0rgK.11*/1213import Footer from "components/landing/footer";14import Head from "components/landing/head";15import Header from "components/landing/header";16import { Customize, CustomizeType } from "lib/customize";17import withCustomize from "lib/with-customize";18import useAPI from "lib/hooks/api";19import { Alert, Button, Card, Divider, Layout, Space, Spin } from "antd";20import { useRouter } from "next/router";21import type { Description } from "@cocalc/util/db-schema/token-actions";22import { capitalize } from "@cocalc/util/misc";23import { useState } from "react";24import { getTokenDescription } from "@cocalc/server/token-actions/handle";25import Markdown from "@cocalc/frontend/editors/slate/static-markdown";26import { Icon, IconName } from "@cocalc/frontend/components/icon";27import getAccountId from "lib/account/get-account";28import InPlaceSignInOrUp from "components/auth/in-place-sign-in-or-up";2930const STYLE = { margin: "30px auto", maxWidth: "600px", fontSize: "14pt" };3132export async function getServerSideProps(context) {33const { id: token_id } = context.params;34const account_id = await getAccountId(context.req);35let description;36try {37description = await getTokenDescription(token_id, account_id);38} catch (error) {39description = {40type: "error",41title: "Error",42details: `${error}`,43cancelText: "",44okText: "OK",45};46}47return await withCustomize({ context, props: { token_id, description } });48}4950interface Props {51customize: CustomizeType;52token_id: string;53description: Description & {54title?: string;55details?: string;56okText?: string;57cancelText?: string;58icon?: IconName;59signIn?: boolean;60};61}6263export default function TokenActions({64customize,65description,66token_id,67}: Props) {68const router = useRouter();69const [doAction, setDoAction] = useState<boolean>(false);70const [loading, setLoading] = useState<boolean>(false);71const title = getTitle(description);7273return (74<Customize value={customize}>75<Head title={title} />76<Layout>77<Header />78{!!description.signIn && (79<div style={{ marginTop: "30px" }}>80<InPlaceSignInOrUp81title={"Please create an account (which is very easy) or sign in"}82/>83</div>84)}85<Dialog86disabled={doAction || !!description.signIn}87loading={loading}88title={title}89details={description.details}90okText={description.okText}91cancelText={description.cancelText}92icon={description.icon}93onConfirm={() => {94setDoAction(true);95}}96onCancel={() => {97setLoading(true);98router.push("/");99}}100/>101{!description.signIn && doAction && <HandleToken token={token_id} />}102<Footer />103</Layout>104</Customize>105);106}107108function Dialog({109disabled,110title,111details,112okText,113cancelText,114icon,115onConfirm,116onCancel,117loading,118}) {119return (120<Card121style={{122margin: "30px auto",123minWidth: "400px",124maxWidth: "min(700px,100%)",125}}126title={127<Space>128{icon && <Icon name={icon} />}129<Markdown value={title} style={{ marginBottom: "-1em" }} />130</Space>131}132>133{details && <Markdown value={details} />}134<Divider />135<div style={{ float: "right" }}>136<Space style={{ marginTop: "8px" }}>137{loading && <Spin />}138{cancelText != "" && (139<Button onClick={onCancel} disabled={disabled || loading}>140{cancelText ?? "Cancel"}141</Button>142)}143{okText != "" && (144<Button145onClick={onConfirm}146disabled={disabled || loading}147type="primary"148>149{okText ?? "Confirm"}150</Button>151)}152</Space>153</div>154</Card>155);156}157158function HandleToken({ token }) {159const { calling, result, error } = useAPI("token-action", { token });160161return (162<div>163{calling && (164<div style={{ ...STYLE, textAlign: "center" }}>165<Spin />166</div>167)}168{error && <Alert showIcon style={STYLE} type="error" message={error} />}169{!calling && result != null && !error && (170<RenderResult data={result.data} />171)}172</div>173);174}175176function RenderResult({ data }: { data: any }) {177if (data?.type == "create-credit") {178const { session, instructions } = data;179return (180<Alert181showIcon182style={STYLE}183type="warning"184message="Make a Payment"185description={<a href={session.url}>{instructions}</a>}186/>187);188} else {189return (190<Alert191showIcon192style={STYLE}193type="success"194message="Success!"195description={data?.text ? <Markdown value={data?.text} /> : undefined}196/>197);198}199}200201function getTitle({ title, type }: Description & { title?: string }) {202if (title) {203return title;204}205switch (type) {206case "make-payment":207return "Make a Payment";208case "disable-daily-statements":209return "Disable Daily Statements";210default:211if (typeof type == "string" && type) {212return capitalize(type.replace(/-/g, " "));213}214return "Token Action";215}216}217218219